package com.aggron.service;

import com.aggron.dao.SysAclMapper;
import com.aggron.dao.SysAclModuleMapper;
import com.aggron.dao.SysDeptMapper;
import com.aggron.dto.AclDto;
import com.aggron.dto.AclModuleLevelDto;
import com.aggron.dto.DeptLevelDto;
import com.aggron.entity.SysAcl;
import com.aggron.entity.SysAclModule;
import com.aggron.entity.SysDept;
import com.aggron.util.CollectionsUtil;
import com.aggron.util.LevelUtil;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 部门树的serivce
 * @author  liuhuan on 2018/6/2.
 */
@Service
public class SysTreeService {

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Autowired
    private SysAclModuleMapper aclModuleMapper;

    @Autowired
    private SysCoreService sysCoreService;

    @Autowired
    private SysAclMapper sysAclMapper;


    /**
     * 查询菜单
     * @return
     */
    public List<AclModuleLevelDto> getMenus() {
        //1.当前用户已经被分配过的权限点
        List<SysAcl> userAclList=sysCoreService.getCurrentUserAclList();
        List<SysAcl> menuAclList=userAclList.stream().filter(sysAcl -> sysAcl.getType()==1).collect(Collectors.toList());
        List<AclDto> menuDotList =Lists.newArrayList();
        for(SysAcl sysAcl:menuAclList){
            menuDotList.add(AclDto.adapter(sysAcl));
        }
        return aclDtoListToTree(menuDotList);
    }



    /**
     * 角色和权限的tree
      * @param roleId
     * @return
     */
    public List<AclModuleLevelDto> roleTree(Integer roleId){

        //1.当前用户已经被分配过的权限点
        List<SysAcl> userAclList=sysCoreService.getCurrentUserAclList();
        //2.当前角色已分配的权限点
        List<SysAcl> roleAclList=sysCoreService.getRoleAclList(roleId);
        //3.当前所有权限点
        List<SysAcl> allSysAclList=sysAclMapper.selectList(null);



        Set<Integer> userAclIdSet=userAclList.stream().map(sysAcl->sysAcl.getId()).collect(Collectors.toSet());
        Set<Integer> roleAclIdSet=roleAclList.stream().map(sysAcl -> sysAcl.getId()).collect(Collectors.toSet());




        List<AclDto> aclDtoList=Lists.newArrayList();
        for (SysAcl sysAcl:allSysAclList){
            AclDto aclDto=AclDto.adapter(sysAcl);
            if(userAclIdSet.contains(sysAcl.getId())){
                aclDto.setHasAcl(true);
            }
            if(roleAclIdSet.contains(sysAcl.getId())){
                aclDto.setChecked(true);
            }
            aclDtoList.add(aclDto);
        }
        return aclDtoListToTree(aclDtoList);
    }

    /**
     * acldtoList
     * @param aclDtoList
     * @return
     */
    private List<AclModuleLevelDto> aclDtoListToTree(List<AclDto> aclDtoList) {
        if(CollectionsUtil.isEmpty(aclDtoList)){
            return Lists.newArrayList();
        }
        List<AclModuleLevelDto> aclModuleLevelDtoList=aclModuleTree();
        Multimap<Integer,AclDto> aclDtoMultimap=ArrayListMultimap.create();
        for (AclDto aclDto:aclDtoList){
            if(aclDto.getStatus()==1){
                aclDtoMultimap.put(aclDto.getAclModuleId(),aclDto);
            }
        }
        bindAclWithOrder(aclModuleLevelDtoList,aclDtoMultimap);
        return aclModuleLevelDtoList;
    }

    /**
     * 绑定权限点到权限模块
     * @param aclModuleLevelDtoList
     * @param aclDtoMultimap
     */
    private void bindAclWithOrder(List<AclModuleLevelDto> aclModuleLevelDtoList, Multimap<Integer, AclDto> aclDtoMultimap) {
        if(CollectionsUtil.isEmpty(aclModuleLevelDtoList)){
            return;
        }
        for (AclModuleLevelDto aclModuleLevelDto:aclModuleLevelDtoList ){
            List<AclDto> aclDtoList=(List<AclDto> )aclDtoMultimap.get(aclModuleLevelDto.getId());
            if(!CollectionsUtil.isEmpty(aclDtoList)){
                Collections.sort(aclDtoList,aclDtoComparator);
                aclModuleLevelDto.setAclDtoList(aclDtoList);

            }
            bindAclWithOrder(aclModuleLevelDto.getChildren(),aclDtoMultimap);

        }
    }


    /**
     * 权限模块的树
     * @return
     */
    public List<AclModuleLevelDto> aclModuleTree(){
        List<SysAclModule> sysAclModuleList=aclModuleMapper.selectList(null);
        List<AclModuleLevelDto> aclModuleLevelDtoList= Lists.newArrayList();
        for (SysAclModule sysAclModule:sysAclModuleList) {
            aclModuleLevelDtoList.add(AclModuleLevelDto.adapter(sysAclModule));
        }
        return aclModuleLevelDtoListToTree(aclModuleLevelDtoList);
    }

    /**
     * 适配出一颗权限树
     * @param aclModuleLevelDtoList
     * @return
     */
    private List<AclModuleLevelDto> aclModuleLevelDtoListToTree(List<AclModuleLevelDto> aclModuleLevelDtoList) {
        if(CollectionsUtil.isEmpty(aclModuleLevelDtoList)){
            return null;
        }
        //(level,List<AclModuleLevelDto>)
        Multimap<String,AclModuleLevelDto> levelAclModulemap=ArrayListMultimap.create();
        List<AclModuleLevelDto> rootAclModuleList=Lists.newArrayList();
        for(AclModuleLevelDto aclModuleLevelDto:aclModuleLevelDtoList){
            levelAclModulemap.put(aclModuleLevelDto.getLevel(),aclModuleLevelDto);
            if(LevelUtil.ROOT.equals(aclModuleLevelDto.getLevel())){
                rootAclModuleList.add(aclModuleLevelDto);
            }

        }
        Collections.sort(rootAclModuleList,aclModuleLevelDtoComparator);
        transformAclModuleTree(rootAclModuleList,LevelUtil.ROOT,levelAclModulemap);
        return rootAclModuleList;
    }

    /**
     * 递归出所有的树
     * @param aclModuleList
     * @param level
     * @param levelAclModulemap
     */
    private void transformAclModuleTree(List<AclModuleLevelDto> aclModuleList, String level, Multimap<String, AclModuleLevelDto> levelAclModulemap) {
        for (AclModuleLevelDto aclModuleLevelDto:aclModuleList) {
            //遍历该层的元素
            //处理当前层级的元素
            //得到当前及对应的level,这步很关键
            String levelTemp=LevelUtil.calculateLevel(level,aclModuleLevelDto.getId());
            //得到当前的元素
            List<AclModuleLevelDto> aclModuleLevelDtoListTemp=(List<AclModuleLevelDto>)levelAclModulemap.get(levelTemp);
            if(!CollectionsUtil.isEmpty(aclModuleLevelDtoListTemp)){
                //排序
                Collections.sort(aclModuleLevelDtoListTemp,aclModuleLevelDtoComparator);
                //设置下一层模块名称
                aclModuleLevelDto.setChildren(aclModuleLevelDtoListTemp);
                //处理下一层的元素
                transformAclModuleTree(aclModuleLevelDtoListTemp,levelTemp,levelAclModulemap);
            }
        }
    }

    /**
     * 部门树
     * @return
     */
    public List<DeptLevelDto> deptTree(){
        List<SysDept> sysDeptList=sysDeptMapper.selectList(null);
        List<DeptLevelDto> deptLevelDtoList= Lists.newArrayList();
        for (SysDept sysDept:sysDeptList) {
            deptLevelDtoList.add(DeptLevelDto.adapt(sysDept));
        }
        return deptLevelDtoListToTree(deptLevelDtoList);
    }

    /**
     * 适配出一颗部门树
     * @param deptLevelList
     * @return
     */
    private   List<DeptLevelDto> deptLevelDtoListToTree(List<DeptLevelDto> deptLevelList){
        if(CollectionsUtil.isEmpty(deptLevelList)){
            return null;
        }
        //(level,List<DeptLevelDto>)
        Multimap<String,DeptLevelDto> levelDeptmap= ArrayListMultimap.create();

        List<DeptLevelDto> rootDeptList=Lists.newArrayList();
        for(DeptLevelDto deptLevelDto:deptLevelList){
            levelDeptmap.put(deptLevelDto.getLevel(),deptLevelDto);
            if(LevelUtil.ROOT.equals(deptLevelDto.getLevel())){
                rootDeptList.add(deptLevelDto);
            }
        }
        //按照seq从小到大排序
        Collections.sort(rootDeptList,deptLevelDtoComparator);
        //递归生成树
        transformDeptTree(rootDeptList,LevelUtil.ROOT,levelDeptmap);
        return rootDeptList;
    }

    /**
     * 递归出部门树
     * @param deptDtoList
     * @param level
     * @param levelDeptmap
     */
    private void transformDeptTree(List<DeptLevelDto> deptDtoList,String level,Multimap<String,DeptLevelDto> levelDeptmap){
        for (DeptLevelDto deptLevelDto:deptDtoList) {
            //遍历该层的元素
            //处理当前层级的元素
            String nextLevel=LevelUtil.calculateLevel(level,deptLevelDto.getId());
            //处理下一层
            List<DeptLevelDto> tempDeptList=(List<DeptLevelDto>)levelDeptmap.get(nextLevel);
            if(!CollectionsUtil.isEmpty(tempDeptList)){
                Collections.sort(tempDeptList,deptLevelDtoComparator);
                //设置下一层部门
                deptLevelDto.setChildren(tempDeptList);
                //处理下一层
                transformDeptTree(tempDeptList,nextLevel,levelDeptmap);
            }

        }
    }

    /**
     * dept排序
     */
    private  Comparator<DeptLevelDto> deptLevelDtoComparator=new Comparator<DeptLevelDto>(){
        @Override
        public int compare(DeptLevelDto o1, DeptLevelDto o2) {
            return o1.getSeq()-o2.getSeq();
        }
    };

    /**
     * aclModuleLevel的排序
     */
    private  Comparator<AclModuleLevelDto> aclModuleLevelDtoComparator=new Comparator<AclModuleLevelDto>(){
        @Override
        public int compare(AclModuleLevelDto o1, AclModuleLevelDto o2) {
            return o1.getSeq()-o2.getSeq();
        }
    };

    /**
     * aclDto的排序
     */
    private  Comparator<AclDto> aclDtoComparator=new Comparator<AclDto>(){
        @Override
        public int compare(AclDto o1, AclDto o2) {
            return o1.getSeq()-o2.getSeq();
        }
    };


}
